package com.my.db.dataInsert;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sql.DataSource;
import java.io.*;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

/**
 * service_order 表批量插入工具类----单纯插入数据，不考虑种植时间等
 * 特性：可配置插入量、随机生成联系人/电话、作物-图片关联、多线程批量插入、事务回滚
 * 特性：分批次处理、批量更新、事务回滚（存储处理数据的文件，回滚sql）、多线程处理、连接池管理
 */
public class ServiceOrderBatchInsertDemo {

    // ============================ 1. 日志配置 ============================
    private static final Logger logger = LoggerFactory.getLogger(ServiceOrderBatchInsertDemo.class);

    // ============================ 2. 数据库连接配置（需根据实际环境修改） ============================
    private static final String DB_URL = "jdbc:mysql://xxx:6777/yilong?" +
            "useUnicode=true&characterEncoding=utf8" +
            "&autoReconnect=true" +
            "&zeroDateTimeBehavior=CONVERT_TO_NULL" +
            "&transformedBitIsBoolean=true" +
            "&allowPublicKeyRetrieval=true" +
            "&serverTimezone=Asia/Shanghai";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "156"; // 填写实际数据库密码
    private static DataSource dataSource; // Hikari连接池

    // ============================ 3. 插入参数配置（可按需修改） ============================
    // 3.1 核心插入配置
    private static final int TOTAL_INSERT_COUNT = 1300; // 总插入记录数（可定义）
    private static final int TOTAL_NUM_SUM = 2000; // 所有记录num字段总和（可定义）
    private static final BigDecimal UNIT_PRICE = new BigDecimal("50.00"); // 单价（total_amount = num * unit_price）
    private static final String DATA_FILE_PATH = "E:\\临时\\service_order_inserted_ids.txt"; // 记录插入ID的文件（用于回滚）

    // 3.2 处理性能配置
    private static final int BATCH_SIZE = 500; // 每批次插入条数（避免SQL过长）
    private static final int THREAD_POOL_SIZE = 4; // 线程池大小（根据CPU核心数调整）

    // 3.3 固定字段值（从原有数据提取，无需修改）
    private static final String CREATE_BY = "minAppName126";
    private static final String USER_ID = "1914857210854903810";
    private static final int ORDER_STATUS = 3;
    private static final int ALLOT_STATUS = 0;
    private static final int ORDER_TYPE = 1;
    private static final int SERVICE_PROJECT_TYPE = 1;
    private static final String SYS_ORG_CODE = "1780120784835211268";
    private static final String SERVICE_SUBJECT = "1780120784835211268";
    private static final int DEL_FLAG = 0;

    // 3.4 关联配置（作物-图片映射，需与实际业务匹配）
    private static final Map<String, String> CROP_IMG_MAP = new HashMap<String, String>() {{
//        put("小麦", "https://nong.yaxingtech.com.cn:8006/api/jeecg-boot/sys/common/static/temp/20241126213000_1732627820020.jpg");
        put("水稻", "https://nong.yaxingtech.com.cn:8006/api/jeecg-boot/sys/common/static/temp/20241126212811_1732627709217.jpg");
        put("玉米", "https://nong.yaxingtech.com.cn:8006/api/jeecg-boot/sys/common/static/temp/20241126213000_1732627820020.jpg");
        put("大豆", "https://nong.yaxingtech.com.cn:8006/api/jeecg-boot/sys/common/static/temp/20241126212811_1732627709217.jpg");
    }};
    //机播
    private static final Map<String, String> CROP_IMG_MAP1 = new HashMap<String, String>() {{
        put("大豆", "https://nong.yaxingtech.com.cn:8006/api/jeecg-boot/sys/common/static/temp/20241126212811_1732627709217.jpg");
        put("玉米", "https://nong.yaxingtech.com.cn:8006/api/jeecg-boot/sys/common/static/temp/20241126212811_1732627709217_1744968322950.jpg");
    }};
    //打药
    private static final Map<String, String> CROP_IMG_MAP2 = new HashMap<String, String>() {{
        put("打药", "https://nong.yaxingtech.com.cn:8006/api/jeecg-boot/sys/common/static/temp/20241126213257_1732627994114.jpg");
    }};
    //采收
    private static final Map<String, String> CROP_IMG_MAP3 = new HashMap<String, String>() {{
        put("水稻", "https://nong.yaxingtech.com.cn:8006/api/jeecg-boot/sys/common/static/temp/123_1755599109582.png");
        put("玉米", "https://nong.yaxingtech.com.cn:8006/api/jeecg-boot/sys/common/static/temp/玉米采收_1756194845309.png");
    }};
    private static final List<String> COMMON_ADDRESSES = Arrays.asList( // 常见地址（随机选择）
            "双胜镇永盛路14号", "马鞍镇东风街8号", "仪陇县双胜镇永久村",
            "双胜镇火井村5组", "马鞍镇建设南路12号", "仪陇县金城镇文化路"
    );
    private static final List<String> SERVICE_PROJECTS = Arrays.asList("旱田机耕", "机耕"); // 服务项目（随机选择）
    private static final List<String> SERVICE_PROJECTS2 = Arrays.asList("机播玉米", "机播水稻", "机播大豆"); // 服务项目（随机选择）
    private static final List<String> SERVICE_PROJECTS3 = Arrays.asList("无人机施肥"); // 服务项目（随机选择）
    private static final List<String> SERVICE_PROJECTS4 = Arrays.asList("机收水稻","机收大豆","机收玉米"); // 服务项目（随机选择）


    // 3.5 随机生成配置
    private static final String[] SURNAMES = {"李", "王", "张", "刘", "陈", "杨", "赵", "黄", "周", "吴", "徐", "孙", "胡"};
    private static final String[] FIRST_NAMES = {"伟", "芳", "军", "洋", "敏", "静", "强", "丽", "磊", "婷", "明", "浩", "娟"};
    private static final String[] PHONE_PREFIXES = {"130", "131", "132", "133", "134", "135", "136", "137", "138", "139", "147", "150", "151", "152", "153", "155", "156", "157", "158", "159", "170", "171", "173", "175", "176", "177", "178", "180", "181", "182", "183", "184", "185", "186", "187", "188", "189", "198", "199"};
    private static final int CREATE_TIME_RANGE_DAYS = 180; // create_time范围：近180天内
    private static final int[] EXP_COM_TIME_DAYS = {3, 4, 5}; // exp_com_time：比create_time晚3-5天

    // 3.6 ID生成器（雪花算法，确保ID唯一）
    private static final SnowflakeIdGenerator ID_GENERATOR = new SnowflakeIdGenerator(1, 1);

    // ============================ 4. 静态代码块（初始化连接池） ============================
    static {
        try {
            HikariConfig config = new HikariConfig();
            config.setJdbcUrl(DB_URL);
            config.setUsername(DB_USER);
            config.setPassword(DB_PASSWORD);
            config.setMaximumPoolSize(THREAD_POOL_SIZE);
            config.setConnectionTimeout(30000);
            config.setIdleTimeout(600000);
            config.setMaxLifetime(1800000);
            config.setMinimumIdle(2);
            dataSource = new HikariDataSource(config);
            logger.info("数据库连接池初始化成功");
        } catch (Exception e) {
            logger.error("数据库连接池初始化失败", e);
            throw new RuntimeException("连接池初始化异常", e);
        }
    }

    // ============================ 5. 内部实体类 ============================
    /**
     * 插入数据封装类
     */
    @Data
    @AllArgsConstructor
    private static class OrderInsertData {
        private String id; // 主键ID
        private String contactPerson; // 联系人
        private String phone; // 电话
        private String address; // 地址
        private int num; // 数量
        private String serviceProject; // 服务项目
        private String crop; // 作物
        private String shopImg; // 图片
        private Timestamp createTime; // 创建时间
        private Timestamp expComTime; // 预计完成时间
        private BigDecimal totalAmount; // 总金额（num * unit_price）
    }

    /**
     * 雪花算法ID生成器（确保ID唯一，适配表中ID格式）
     */
    private static class SnowflakeIdGenerator {
        private final long workerId; // 工作节点ID
        private final long datacenterId; // 数据中心ID
        private long sequence = 0L; // 序列号
        private long lastTimestamp = -1L; // 上次生成ID的时间戳

        // 构造器（workerId和datacenterId范围：0-31）
        public SnowflakeIdGenerator(long workerId, long datacenterId) {
            if (workerId > 31 || workerId < 0) {
                throw new IllegalArgumentException("workerId必须在0-31之间");
            }
            if (datacenterId > 31 || datacenterId < 0) {
                throw new IllegalArgumentException("datacenterId必须在0-31之间");
            }
            this.workerId = workerId;
            this.datacenterId = datacenterId;
        }

        // 生成唯一ID（线程安全）
        public synchronized String nextId() {
            long timestamp = System.currentTimeMillis();
            // 解决时钟回拨问题
            if (timestamp < lastTimestamp) {
                throw new RuntimeException("时钟回拨，拒绝生成ID");
            }
            // 同一时间戳内序列号自增
            if (lastTimestamp == timestamp) {
                sequence = (sequence + 1) & 4095; // 序列号12位，最大值4095
                if (sequence == 0) {
                    timestamp = nextMillis(lastTimestamp); // 序列号用尽，等待下一时间戳
                }
            } else {
                sequence = 0L;
            }
            lastTimestamp = timestamp;
            // 雪花算法公式：时间戳(41位) + 数据中心ID(5位) + 工作节点ID(5位) + 序列号(12位)
            long id = ((timestamp - 1609459200000L) << 22) // 时间戳偏移（以2021-01-01为起点）
                    | (datacenterId << 17)
                    | (workerId << 12)
                    | sequence;
            return String.valueOf(id);
        }

        // 获取下一个时间戳（毫秒）
        private long nextMillis(long lastTimestamp) {
            long timestamp = System.currentTimeMillis();
            while (timestamp <= lastTimestamp) {
                timestamp = System.currentTimeMillis();
            }
            return timestamp;
        }
    }

    // ============================ 6. 随机生成工具方法 ============================
    /**
     * 随机生成联系人（姓氏+名字）
     */
    private static String randomContactPerson() {
        Random random = new Random();
        String surname = SURNAMES[random.nextInt(SURNAMES.length)];
        String firstName = FIRST_NAMES[random.nextInt(FIRST_NAMES.length)];
        return surname + firstName;
    }

    /**
     * 随机生成手机号（11位，符合中国手机号规则）
     */
    private static String randomPhone() {
        Random random = new Random();
        String prefix = PHONE_PREFIXES[random.nextInt(PHONE_PREFIXES.length)];
        StringBuilder suffix = new StringBuilder();
        for (int i = 0; i < 9; i++) { // 前缀3位 + 后缀9位 = 11位
            suffix.append(random.nextInt(10));
        }
        return prefix + suffix;
    }

    /**
     * 随机选择作物和对应的图片
     */
    private static Map.Entry<String, String> randomCropAndImg() {
        List<Map.Entry<String, String>> entries = new ArrayList<>(CROP_IMG_MAP.entrySet());
        return entries.get(new Random().nextInt(entries.size()));
    }

    /**
     * 随机生成create_time（近N天内）
     */
    private static Timestamp randomCreateTime() {
        Random random = new Random();
        long currentTime = System.currentTimeMillis();
        long randomDays = random.nextInt(CREATE_TIME_RANGE_DAYS);
        long createTimeMillis = currentTime - (randomDays * 24L * 60 * 60 * 1000);
        return new Timestamp(createTimeMillis);
    }

    /**
     * 生成exp_com_time（比create_time晚3-7天）
     */
    private static Timestamp generateExpComTime(Timestamp createTime) {
        Random random = new Random();
        int addDays = EXP_COM_TIME_DAYS[random.nextInt(EXP_COM_TIME_DAYS.length)];
        long expComTimeMillis = createTime.getTime() + (addDays * 24L * 60 * 60 * 1000);
        return new Timestamp(expComTimeMillis);
    }

    /**
     * 分摊总num到每条记录（确保总和为TOTAL_NUM_SUM）
     */
    private static List<Integer> splitTotalNum() {
        List<Integer> numList = new ArrayList<>();
        int baseNum = TOTAL_NUM_SUM / TOTAL_INSERT_COUNT; // 基础值
        int remainder = TOTAL_NUM_SUM % TOTAL_INSERT_COUNT; // 余数（分摊到前remainder条记录）

        for (int i = 0; i < TOTAL_INSERT_COUNT; i++) {
            if (i < remainder) {
                numList.add(baseNum + 1);
            } else {
                numList.add(baseNum);
            }
        }
        // 随机打乱（避免前几条固定多1）
        Collections.shuffle(numList);
        return numList;
    }

    // ============================ 7. 核心插入逻辑 ============================
    /**
     * 生成所有待插入的数据列表
     */
    private static List<OrderInsertData> generateInsertDataList() {
        List<OrderInsertData> dataList = new ArrayList<>(TOTAL_INSERT_COUNT);
        List<Integer> numList = splitTotalNum(); // 分摊后的num列表

        for (int i = 0; i < TOTAL_INSERT_COUNT; i++) {
            // 1. 生成唯一ID
            String id = ID_GENERATOR.nextId();

            // 2. 随机字段
            String contactPerson = randomContactPerson();
            String phone = randomPhone();
            String address = COMMON_ADDRESSES.get(new Random().nextInt(COMMON_ADDRESSES.size()));
            String serviceProject = SERVICE_PROJECTS.get(new Random().nextInt(SERVICE_PROJECTS.size()));
            Map.Entry<String, String> cropImg = randomCropAndImg();
            String crop = cropImg.getKey();
            String shopImg = cropImg.getValue();
            int num = numList.get(i);

            // 3. 时间字段
            Timestamp createTime = randomCreateTime();
            Timestamp expComTime = generateExpComTime(createTime);

            // 4. 金额字段（total_amount = num * unit_price）
            BigDecimal totalAmount = UNIT_PRICE.multiply(new BigDecimal(num));

            // 5. 封装数据
            dataList.add(new OrderInsertData(
                    id, contactPerson, phone, address, num, serviceProject,
                    crop, shopImg, createTime, expComTime, totalAmount
            ));
        }
        logger.info("待插入数据生成完成，共{}条", dataList.size());
        return dataList;
    }

    /**
     * 处理单个批次的插入
     */
    private static int processInsertBatch(List<OrderInsertData> batchData, BufferedWriter writer) throws SQLException, IOException {
        if (batchData.isEmpty()) {
            logger.info("当前批次数据为空，跳过插入");
            return 0;
        }

        // 插入SQL（对应service_order表所有字段，NULL字段直接传NULL）
        String insertSql = "INSERT INTO `yilong`.`service_order` (" +
                "`id`, `goods_id`, `specification`, `allot_status`, `agricultural_machinery_id`, " +
                "`goods_shopping_car_uid`, `leave_message`, `goods_address_id`, `create_by`, `create_time`, " +
                "`update_by`, `update_time`, `sys_org_code`, `service_project`, `order_no`, " +
                "`order_type`, `order_status`, `send_status`, `pay_no`, `pay_time`, " +
                "`service_subject`, `service_project_type`, `contact_person`, `phone`, `address`, " +
                "`num`, `exp_com_time`, `unit_price`, `cd_reason`, `total_amount`, " +
                "`shop_img`, `crop`, `user_id`, `express_com`, `express_num`, `del_flag`" +
                ") VALUES (" +
                "?, NULL, NULL, ?, NULL, " +
                "NULL, NULL, NULL, ?, ?, " +
                "NULL, NULL, ?, ?, NULL, " +
                "?, ?, NULL, NULL, NULL, " +
                "?, ?, ?, ?, ?, " +
                "?, ?, ?, NULL, ?, " +
                "?, ?, ?, NULL, NULL, ?" +
                ")";

        try (Connection conn = dataSource.getConnection()) {
            conn.setAutoCommit(false); // 开启事务
            try (PreparedStatement ps = conn.prepareStatement(insertSql)) {
                // 批量设置参数
                for (OrderInsertData data : batchData) {
                    int paramIndex = 1;
                    ps.setString(paramIndex++, data.getId()); // 1. id
                    ps.setInt(paramIndex++, ALLOT_STATUS); // 2. allot_status
                    ps.setString(paramIndex++, CREATE_BY); // 3. create_by
                    ps.setTimestamp(paramIndex++, data.getCreateTime()); // 4. create_time
                    ps.setString(paramIndex++, SYS_ORG_CODE); // 5. sys_org_code
                    ps.setString(paramIndex++, data.getServiceProject()); // 6. service_project
                    ps.setInt(paramIndex++, ORDER_TYPE); // 7. order_type
                    ps.setInt(paramIndex++, ORDER_STATUS); // 8. order_status
                    ps.setString(paramIndex++, SERVICE_SUBJECT); // 9. service_subject
                    ps.setInt(paramIndex++, SERVICE_PROJECT_TYPE); // 10. service_project_type
                    ps.setString(paramIndex++, data.getContactPerson()); // 11. contact_person
                    ps.setString(paramIndex++, data.getPhone()); // 12. phone
                    ps.setString(paramIndex++, data.getAddress()); // 13. address
                    ps.setInt(paramIndex++, data.getNum()); // 14. num
                    ps.setTimestamp(paramIndex++, data.getExpComTime()); // 15. exp_com_time
                    ps.setBigDecimal(paramIndex++, UNIT_PRICE); // 16. unit_price
                    ps.setBigDecimal(paramIndex++, data.getTotalAmount()); // 17. total_amount
                    ps.setString(paramIndex++, data.getShopImg()); // 18. shop_img
                    ps.setString(paramIndex++, data.getCrop()); // 19. crop
                    ps.setString(paramIndex++, USER_ID); // 20. user_id
                    ps.setInt(paramIndex++, DEL_FLAG); // 21. del_flag

                    ps.addBatch(); // 添加到批处理
                }

                // 执行批处理
                int[] affectedRows = ps.executeBatch();
                conn.commit(); // 提交事务

                // 记录插入的ID到文件（用于回滚）
                synchronized (writer) {
                    for (OrderInsertData data : batchData) {
                        writer.write(data.getId());
                        writer.newLine();
                    }
                }

                int totalAffected = Arrays.stream(affectedRows).sum();
                logger.info("批次插入完成，处理{}条，影响行数{}", batchData.size(), totalAffected);
                return totalAffected;
            } catch (SQLException e) {
                conn.rollback(); // 异常回滚
                logger.error("批次插入失败，已回滚", e);
                throw e;
            }
        }
    }

    /**
     * 主批量插入方法
     */
    public static void performBatchInsert() throws SQLException, InterruptedException, IOException {
        // 1. 生成待插入数据
        List<OrderInsertData> allData = generateInsertDataList();
        if (allData.isEmpty()) {
            logger.warn("无待插入数据，退出流程");
            return;
        }

        // 2. 初始化线程池和计数器
        ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
        AtomicLong totalAffected = new AtomicLong(0);
        BufferedWriter writer = new BufferedWriter(new FileWriter(DATA_FILE_PATH));

        // 3. 分批次提交任务
        int totalBatches = (int) Math.ceil((double) allData.size() / BATCH_SIZE);
        for (int i = 0; i < totalBatches; i++) {
            int start = i * BATCH_SIZE;
            int end = Math.min(start + BATCH_SIZE, allData.size());
            List<OrderInsertData> batch = allData.subList(start, end);

            executorService.submit(() -> {
                try {
                    int affected = processInsertBatch(batch, writer);
                    totalAffected.addAndGet(affected);
                } catch (SQLException | IOException e) {
                    logger.error("批次插入失败，尝试重试", e);
                    // 重试逻辑（1次重试）
                    try {
                        Thread.sleep(1000);
                        int affected = processInsertBatch(batch, writer);
                        totalAffected.addAndGet(affected);
                        logger.info("批次重试插入成功");
                    } catch (SQLException | IOException | InterruptedException ex) {
                        logger.error("批次重试失败，该批次数据未插入", ex);
                    }
                }
            });
        }

        // 4. 关闭线程池和文件流
        executorService.shutdown();
        if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
            executorService.shutdownNow();
            logger.warn("线程池等待超时，已强制关闭");
        }
        writer.close();

        // 5. 输出结果
        logger.info("批量插入完成！总插入记录数：{}，总影响行数：{}，总num：{}，总金额：{}",
                TOTAL_INSERT_COUNT, totalAffected.get(), TOTAL_NUM_SUM,
                UNIT_PRICE.multiply(new BigDecimal(TOTAL_NUM_SUM)));
    }

    // ============================ 8. 回滚逻辑（删除插入的数据） ============================
    /**
     * 从文件读取插入的ID，批量回滚（删除）
     */
    public static void rollbackInsertedData() throws IOException, SQLException, InterruptedException {
        // 1. 读取文件中的ID
        List<String> insertedIds = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(new FileReader(DATA_FILE_PATH))) {
            String line;
            while ((line = reader.readLine()) != null) {
                line = line.trim();
                if (!line.isEmpty()) {
                    insertedIds.add(line);
                }
            }
        }
        if (insertedIds.isEmpty()) {
            logger.warn("回滚文件中无ID记录，无需回滚");
            return;
        }
        logger.info("读取到待回滚的ID数量：{}", insertedIds.size());

        // 2. 分批次删除
        ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
        AtomicLong totalDeleted = new AtomicLong(0);
        int totalBatches = (int) Math.ceil((double) insertedIds.size() / BATCH_SIZE);

        for (int i = 0; i < totalBatches; i++) {
            int start = i * BATCH_SIZE;
            int end = Math.min(start + BATCH_SIZE, insertedIds.size());
            List<String> batchIds = insertedIds.subList(start, end);

            executorService.submit(() -> {
                try {
                    int deleted = processRollbackBatch(batchIds);
                    totalDeleted.addAndGet(deleted);
                } catch (SQLException e) {
                    logger.error("批次回滚失败，尝试重试", e);
                    try {
                        Thread.sleep(1000);
                        int deleted = processRollbackBatch(batchIds);
                        totalDeleted.addAndGet(deleted);
                        logger.info("批次重试回滚成功");
                    } catch (SQLException | InterruptedException ex) {
                        logger.error("批次重试回滚失败，该批次ID未删除", ex);
                    }
                }
            });
        }

        // 3. 关闭线程池
        executorService.shutdown();
        if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
            executorService.shutdownNow();
            logger.warn("线程池等待超时，已强制关闭");
        }

        // 4. 输出回滚结果
        logger.info("回滚完成！总删除记录数：{}", totalDeleted.get());
    }

    /**
     * 处理单个批次的回滚（删除）
     */
    private static int processRollbackBatch(List<String> batchIds) throws SQLException {
        if (batchIds.isEmpty()) {
            return 0;
        }

        // 构建IN条件（避免SQL注入，用占位符）
        StringBuilder inClause = new StringBuilder();
        for (int i = 0; i < batchIds.size(); i++) {
            inClause.append("?");
            if (i < batchIds.size() - 1) {
                inClause.append(",");
            }
        }
        String deleteSql = "DELETE FROM `yilong`.`service_order` WHERE `id` IN (" + inClause + ")";

        try (Connection conn = dataSource.getConnection()) {
            conn.setAutoCommit(false);
            try (PreparedStatement ps = conn.prepareStatement(deleteSql)) {
                // 设置ID参数
                for (int i = 0; i < batchIds.size(); i++) {
                    ps.setString(i + 1, batchIds.get(i));
                }

                int affectedRows = ps.executeUpdate();
                conn.commit();
                logger.info("批次回滚完成，删除ID数量：{}，影响行数：{}", batchIds.size(), affectedRows);
                return affectedRows;
            } catch (SQLException e) {
                conn.rollback();
                logger.error("批次回滚失败，已回滚", e);
                throw e;
            }
        }
    }

    // ============================ 9. 程序入口（执行插入或回滚） ============================
    public static void main(String[] args) {
        try {
            // 执行批量插入（注释掉则执行回滚）
            performBatchInsert();

            // 执行回滚（需先注释插入，再解开下面注释）
            // rollbackInsertedData();
        } catch (Exception e) {
            logger.error("程序执行失败", e);
        }
    }
}